#include <QApplication>
#include <QtWidgets>
#include "coloritem.h"
#include "dropitem.h"

class GraphicsView : public QGraphicsView
{
public:
    GraphicsView(QGraphicsScene *scene) : QGraphicsView(scene)
    {
    }

protected:
    void resizeEvent(QResizeEvent *) override
    {
    }
};
/*
QGraphicsScene类提供了一个用于管理大量2D图形项的曲面。
该类充当QGraphicsItems的容器。它与QGraphicsView一起用于在二维曲面上可视化图形项目，如直线、矩形、文本，甚至自定义项目。QGraphicsScene是图形视图框架的一部分。
QGraphicsScene还提供了一些功能，使您能够有效地确定项目的位置，并确定哪些项目在场景的任意区域内可见。使用QGraphicsView小部件，您可以可视化整个场景，也可以放大并仅查看场景的一部分。
请注意，QGraphicsScene没有自己的视觉外观；它只管理项目。您需要创建一个QGraphicsView小部件来可视化场景。
要将项目添加到场景中，首先要构建一个QGraphicsScene对象。然后，您有两个选项：通过调用addItem（）添加现有的QGraphicsItem对象，或者您可以调用其中一个方便函数addEllipse（）、addLine（）、addPath（）、add Pixmap（）、add Polygon（）、add Rect（）或addText（），它们都返回一个指向新添加项的指针。添加了这些功能的项目的尺寸相对于项目的坐标系，并且项目在场景中的位置初始化为（0，0）。
然后可以使用QGraphicsView可视化场景。当场景发生变化时（例如，当项目移动或变换时），QGraphicsScene会发出changed（）信号。若要删除项目，请调用removeItem（）。
QGraphicsScene使用索引算法来有效地管理项目的位置。默认情况下，使用BSP（二进制空间分区）树；适用于大多数项目保持静止（即不四处移动）的大型场景的算法。您可以通过调用setItemIndexMethod（）来选择禁用此索引。有关可用索引算法的更多信息，请参阅itemIndexMethod属性。
场景的边界矩形是通过调用setSceneRight（）来设置的。项目可以放置在场景中的任何位置，默认情况下场景的大小不受限制。场景rect仅用于内部记账，用于维护场景的项目索引。如果场景矩形未设置，QGraphicsScene将使用itemsBoundingRect（）返回的所有项目的边界区域作为场景矩形。然而，itemsBoundingRect（）是一个相对耗时的函数，因为它通过收集场景中每个项目的位置信息来操作。因此，在大型场景中操作时，应始终将场景设置为rect。
QGraphicsScene最大的优势之一是它能够有效地确定项目的位置。即使场景中有数百万个项目，items（）函数也可以在几毫秒内确定项目的位置。items（）有几个重载：一个是在特定位置查找项，一个是查找多边形或矩形内部或与多边形或矩形相交的项，等等。返回项目的列表按堆叠顺序排序，最上面的项目是列表中的第一个项目。为了方便起见，还有一个itemAt（）函数，它返回给定位置的最上面的项。
QGraphicsScene维护场景的选择信息。要选择项目，请调用setSelectionArea（），要清除当前选择，请调用clearSelection（）。调用selectedItems（）以获取所有选定项目的列表。
事件处理和传播
QGraphicsScene的另一个职责是从QGraphicsView传播事件。要将事件发送到场景，您可以构造一个继承QEvent的事件，然后使用例如QApplication:：sendEvent（）发送它。event（）负责将事件分派到各个项目。一些常见事件由方便事件处理程序处理。例如，按键事件由keyPressEvent（）处理，鼠标按下事件由mousePressEvent（（）处理。
将关键事件交付给重点项目。要设置焦点项，可以调用setFocusItem（），传递接受焦点的项，也可以调用QGraphicsItem:：setFocus（）。调用focusItem（）获取当前的焦点项。为了与小部件兼容，场景还保留自己的焦点信息。默认情况下，场景没有焦点，并且会丢弃所有关键事件。如果调用了setFocus（），或者场景中的某个项目获得了焦点，则场景会自动获得焦点。如果场景具有焦点，hasFocus（）将返回true，关键事件将转发到焦点项（如果有的话）。如果场景失去焦点（即，有人调用clearFocus（）），而项目具有焦点，则场景将保持其项目焦点信息，一旦场景恢复焦点，它将确保最后一个焦点项目恢复焦点。
对于鼠标悬停效果，QGraphicsScene分派悬停事件。如果项目接受悬停事件（请参阅QGraphicsItem:：acceptHoverEvents（）），则当鼠标进入其区域时，它将接收GraphicsSceneHoverEnter事件。当鼠标继续在项目区域内移动时，QGraphicsScene将向其发送GraphicsSceneHoverMove事件。当鼠标离开项目的区域时，该项目将收到GraphicsSceneHoverLeave事件。
所有鼠标事件都将传递到当前鼠标抓取器项目。如果一个项目接受鼠标事件（请参见QGraphicsItem:：acceptedMouseButtons（））并接收鼠标按压，则该项目将成为场景的鼠标抓取器。它一直保持鼠标抓取器，直到在没有按下其他鼠标按钮的情况下接收到鼠标释放。您可以调用mouseGrabberItem（）来确定当前正在抓取鼠标的项目。
*/
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    QGraphicsScene scene(-200, -200, 400, 400);

    for (int i = 0; i < 10; ++i) {
        ColorItem *colorItem = new ColorItem;
        colorItem->setPos(::sin((i * 6.28) / 10.0) * 150,
                          ::cos((i * 6.28) / 10.0) * 150);

        scene.addItem(colorItem);
    }

    DropItem *dropItem = new DropItem;
    dropItem->setPos(0, 0);
    scene.addItem(dropItem);

    GraphicsView view(&scene);
    view.setRenderHint(QPainter::Antialiasing);
    view.setViewportUpdateMode(QGraphicsView::BoundingRectViewportUpdate);
    view.setBackgroundBrush(QColor(230, 200, 167));
    view.setWindowTitle("My Drop Test");
    view.show();

    return a.exec();
}




